package com.example.service.impl;

import com.example.dao.ReviewDao;
import com.example.entity.Review;
import com.example.service.ReviewService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 评价服务实现类
 * @author System
 * @date 2024
 */
@Service
@Transactional
public class ReviewServiceImpl implements ReviewService {
    
    private static final Logger logger = LoggerFactory.getLogger(ReviewServiceImpl.class);
    
    @Autowired
    private ReviewDao reviewDao;
    
    @Override
    public boolean addReview(Review review) {
        try {
            // 参数验证
            if (review == null || review.getUserId() == null || review.getProductId() == null ||
                review.getRating() == null || review.getContent() == null) {
                logger.warn("评价参数不完整");
                return false;
            }
            
            // 评分范围验证
            if (review.getRating() < 1 || review.getRating() > 5) {
                logger.warn("评分超出范围: {}", review.getRating());
                return false;
            }
            
            review.setStatus(1); // 默认通过
            review.setCreateTime(new Date());
            review.setUpdateTime(new Date());
            
            int result = reviewDao.insert(review);
            logger.info("添加评价成功: userId={}, productId={}", review.getUserId(), review.getProductId());
            return result > 0;
        } catch (Exception e) {
            logger.error("添加评价失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public Review getReviewById(Long id) {
        try {
            if (id == null || id <= 0) {
                return null;
            }
            return reviewDao.selectById(id);
        } catch (Exception e) {
            logger.error("查询评价失败: id={}", id, e);
            return null;
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getAllReviews() {
        try {
            return reviewDao.selectAllWithDetails();
        } catch (Exception e) {
            logger.error("查询所有评价失败", e);
            return null;
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getReviewsByProductId(Long productId) {
        try {
            if (productId == null || productId <= 0) {
                return null;
            }
            return reviewDao.selectByProductId(productId);
        } catch (Exception e) {
            logger.error("根据商品ID查询评价失败: productId={}", productId, e);
            return null;
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getReviewsByUserId(Long userId) {
        try {
            if (userId == null || userId <= 0) {
                return null;
            }
            return reviewDao.selectByUserId(userId);
        } catch (Exception e) {
            logger.error("根据用户ID查询评价失败: userId={}", userId, e);
            return null;
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getReviewsByProductIdWithSort(Long productId, String sortBy) {
        try {
            if (productId == null || productId <= 0) {
                return null;
            }
            
            // 验证排序参数
            if (sortBy == null || (!"newest".equals(sortBy) && !"oldest".equals(sortBy) && 
                !"highest".equals(sortBy) && !"lowest".equals(sortBy))) {
                sortBy = "newest"; // 默认按最新排序
            }
            
            return reviewDao.selectByProductIdWithSort(productId, sortBy);
        } catch (Exception e) {
            logger.error("根据商品ID和排序方式查询评价失败: productId={}, sortBy={}", productId, sortBy, e);
            return null;
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getReviewsByPage(int page, int size) {
        try {
            if (page < 1 || size < 1) {
                return null;
            }
            int offset = (page - 1) * size;
            return reviewDao.selectByPage(offset, size);
        } catch (Exception e) {
            logger.error("分页查询评价失败: page={}, size={}", page, size, e);
            return null;
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getReviewsByProductIdWithPage(Long productId, int page, int size) {
        try {
            if (productId == null || productId <= 0 || page < 1 || size < 1) {
                return null;
            }
            int offset = (page - 1) * size;
            return reviewDao.selectByProductIdWithPage(productId, offset, size);
        } catch (Exception e) {
            logger.error("根据商品ID分页查询评价失败: productId={}, page={}, size={}", productId, page, size, e);
            return null;
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getReviewsByRating(Integer rating) {
        try {
            if (rating == null || rating < 1 || rating > 5) {
                return null;
            }
            return reviewDao.selectByRating(rating);
        } catch (Exception e) {
            logger.error("根据评分查询评价失败: rating={}", rating, e);
            return null;
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public int getReviewCount() {
        try {
            return reviewDao.countAll();
        } catch (Exception e) {
            logger.error("统计评价数量失败", e);
            return 0;
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public int getReviewCountByProductId(Long productId) {
        try {
            if (productId == null || productId <= 0) {
                return 0;
            }
            return reviewDao.countByProductId(productId);
        } catch (Exception e) {
            logger.error("根据商品ID统计评价数量失败: productId={}", productId, e);
            return 0;
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public int getReviewCountByUserId(Long userId) {
        try {
            if (userId == null || userId <= 0) {
                return 0;
            }
            return reviewDao.countByUserId(userId);
        } catch (Exception e) {
            logger.error("根据用户ID统计评价数量失败: userId={}", userId, e);
            return 0;
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public Double getAverageRatingByProductId(Long productId) {
        try {
            if (productId == null || productId <= 0) {
                return 0.0;
            }
            Double avgRating = reviewDao.getAverageRatingByProductId(productId);
            return avgRating != null ? Math.round(avgRating * 10.0) / 10.0 : 0.0;
        } catch (Exception e) {
            logger.error("计算商品平均评分失败: productId={}", productId, e);
            return 0.0;
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public Map<Integer, Integer> getRatingStatsByProductId(Long productId) {
        try {
            if (productId == null || productId <= 0) {
                return new HashMap<>();
            }
            
            Map<Integer, Integer> stats = new HashMap<>();
            for (int i = 1; i <= 5; i++) {
                int count = reviewDao.countByProductIdAndRating(productId, i);
                stats.put(i, count);
            }
            return stats;
        } catch (Exception e) {
            logger.error("获取商品评分统计失败: productId={}", productId, e);
            return new HashMap<>();
        }
    }
    
    @Override
    public boolean updateReview(Review review) {
        try {
            if (review == null || review.getId() == null) {
                return false;
            }
            
            // 评分范围验证
            if (review.getRating() != null && (review.getRating() < 1 || review.getRating() > 5)) {
                logger.warn("评分超出范围: {}", review.getRating());
                return false;
            }
            
            review.setUpdateTime(new Date());
            int result = reviewDao.update(review);
            logger.info("更新评价成功: id={}", review.getId());
            return result > 0;
        } catch (Exception e) {
            logger.error("更新评价失败", e);
            return false;
        }
    }
    
    @Override
    public boolean updateReviewStatus(Long id, Integer status) {
        try {
            if (id == null || status == null) {
                return false;
            }
            int result = reviewDao.updateStatus(id, status);
            logger.info("更新评价状态成功: id={}, status={}", id, status);
            return result > 0;
        } catch (Exception e) {
            logger.error("更新评价状态失败: id={}, status={}", id, status, e);
            return false;
        }
    }
    
    @Override
    public boolean deleteReview(Long id) {
        try {
            if (id == null || id <= 0) {
                return false;
            }
            int result = reviewDao.deleteById(id);
            logger.info("删除评价成功: id={}", id);
            return result > 0;
        } catch (Exception e) {
            logger.error("删除评价失败: id={}", id, e);
            return false;
        }
    }
    
    @Override
    public boolean deleteReviews(List<Long> ids) {
        try {
            if (ids == null || ids.isEmpty()) {
                return false;
            }
            int result = reviewDao.deleteByIds(ids);
            logger.info("批量删除评价成功: count={}", result);
            return result > 0;
        } catch (Exception e) {
            logger.error("批量删除评价失败", e);
            return false;
        }
    }
    
    @Override
    public boolean auditReview(Long id, Integer status) {
        try {
            if (id == null || status == null || (status != 1 && status != 2)) {
                return false;
            }
            return updateReviewStatus(id, status);
        } catch (Exception e) {
            logger.error("审核评价失败: id={}, status={}", id, status, e);
            return false;
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Review> getPendingReviews() {
        try {
            return reviewDao.selectByStatus(0); // 状态为0表示待审核
        } catch (Exception e) {
            logger.error("获取待审核评价列表失败", e);
            return null;
        }
    }
    
    @Override
    @Transactional(readOnly = true)
    public boolean hasUserReviewedProduct(Long userId, Long productId) {
        try {
            if (userId == null || productId == null) {
                return false;
            }
            
            List<Review> reviews = reviewDao.selectByUserId(userId);
            if (reviews == null || reviews.isEmpty()) {
                return false;
            }
            
            return reviews.stream().anyMatch(review -> productId.equals(review.getProductId()));
        } catch (Exception e) {
            logger.error("检查用户是否已评价商品失败: userId={}, productId={}", userId, productId, e);
            return false;
        }
    }
}